package main

import (
	"context"
	"sync"
	"sync/atomic"
	"time"

	"gitee.com/clearluo/gotools/net/rpcclient/grpcTest/proto"

	"gitee.com/clearluo/gotools/zaplog"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
)

const (
	//Address string = "172.24.140.27:9000"
	Address string = "192.168.244.89:18100"
)

var (
	conn       *grpc.ClientConn
	w          sync.WaitGroup
	grpcClient proto.SimpleClient
	succ       int64
	fail       int64
)

func init() {
	// 为客户端构造TLS凭证
	creds, err := credentials.NewClientTLSFromFile("../cert/server.crt", "localhost")
	if err != nil {
		zaplog.Infof("Failed to create TLS credentials %v", err)
		return
	}
	_ = creds
	var DialOptions = []grpc.DialOption{
		grpc.WithTransportCredentials(creds),
	}

	// 连接服务端,会断开自动重连
	conn, err = grpc.Dial(Address, DialOptions...)
	if err != nil {
		zaplog.Infof("grpcTest conn err: %v", err)
		return
	}
	conn.GetState()
	// 创建gRPC客户端
	grpcClient = proto.NewSimpleClient(conn)
	w = sync.WaitGroup{}
}
func main() {
	//for {
	//	clientReq(2)
	//	time.Sleep(time.Millisecond * 10)
	//}
	//return
	start := time.Now()
	second := 1
	speed := 1
	w.Add(second * speed)
	for i := 1; i <= second; i++ {
		for j := 0; j < speed; j++ {
			go func(i, j int) {
				clientReqByPool(int32(i*10000 + j)) // 通过统一的去全局tcp连接
				//clientReq(int32(i*10000 + j)) // 每次连接都创建新的tcp
			}(i, j)
		}
		time.Sleep(time.Second)
	}
	w.Wait()
	defer conn.Close()
	zaplog.Infof("use:%v,succ:%v,fail:%v", time.Since(start), succ, fail)
}

func clientReqByPool(n int32) (ret int32) {
	defer func() {
		if n == ret {
			atomic.AddInt64(&succ, 1)
		} else {
			atomic.AddInt64(&fail, 1)
		}
		w.Done()
	}()
	res := proto.SimpleRequest{
		Data: "test",
		Num:  n,
	}
	//zaplog.Warnf("wait n:%v", n)
	ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*3100)
	defer cancel()
	resp, err := grpcClient.GetSimpleInfo(ctx, &res)
	if err != nil {
		zaplog.Infof("stream get from server err: %v", err)
		return 0
	}
	//zaplog.Infof("get from server,code,%v,value: %v", resp.Code, resp.Value)
	return resp.Code
}

func clientReq(n int32) (ret int32) {
	defer func() {
		if n == ret {
			atomic.AddInt64(&succ, 1)
		} else {
			atomic.AddInt64(&fail, 1)
		}
		w.Done()
	}()

	//*************************
	creds, err := credentials.NewClientTLSFromFile("../cert/server.crt", "localhost")
	if err != nil {
		zaplog.Infof("Failed to create TLS credentials %v", err)
		return
	}

	var DialOptions = []grpc.DialOption{
		grpc.WithTransportCredentials(creds),
	}

	// 连接服务端
	conn, err = grpc.Dial(Address, DialOptions...)
	if err != nil {
		zaplog.Infof("grpcTest conn err: %v", err)
		return
	}
	conn.GetState()
	// 创建gRPC客户端
	newClient := proto.NewSimpleClient(conn)
	//*************************
	res := proto.SimpleRequest{
		Data: "test",
		Num:  n,
	}
	//zaplog.Warnf("wait n:%v", n)
	ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*900)
	defer cancel()
	resp, err := newClient.GetSimpleInfo(ctx, &res)
	if err != nil {
		//zaplog.Infof("stream get from server err: %v", err)
		return 0
	}
	//zaplog.Infof("get from server,code,%v,value: %v", resp.Code, resp.Value)
	return resp.Code
}
